package com.sevenre.trackre.driver.network;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CopyOnWriteArrayList;

import com.sevenre.trackre.driver.datatypes.BusPosition;
import com.sevenre.trackre.driver.utils.NetworkConnectivity;
import com.sevenre.trackre.driver.utils.Utils;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings.Secure;
import android.util.Log;

public class TrackService extends Service implements LocationListener {

	LocationManager locationManager;
	Location mLocation;
	Context mContext;
	String mBestProvider;
	CopyOnWriteArrayList<BusPosition> safeList = new CopyOnWriteArrayList<BusPosition>();
	double mLat, mLng, mSpeed, mTime, mDistance = 0;
	boolean mFlag = true;
	public static final String TAG = TrackService.class.getSimpleName();
	public static boolean serviceStatus = true;
	Timer timer1, timer2;
	public static String mScheduleID;

	@Override
	public void onCreate() {
		super.onCreate();
		mContext = this;
		initializeLocationParameters();
		timer1 = new Timer();
		timer2 = new Timer();
		BusPosition.setDeviceId(Secure.getString(getContentResolver(),
				Secure.ANDROID_ID));
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		timer1.scheduleAtFixedRate(addTask, 1000, 1000);
		timer2.scheduleAtFixedRate(uploadTask, 1000, 1250);

		IntentFilter filter = new IntentFilter();
		filter.addAction(Utils.STATUS_CHANGED_INTENT);
		registerReceiver(mStatusReceiver, filter);
		mScheduleID = intent.getStringExtra("ScheduleId");
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		timer1.cancel();
		timer2.cancel();
		unregisterReceiver(mStatusReceiver);
		uploadTask.run();
		if (mFlag) {
			safeList.clear();
		}
		super.onDestroy();
	}

	BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {

			final String status = intent.getStringExtra(Utils.STATUS);
			if (status.contains("STOP")) {
				stopSelf();
			} else if (status.contains("PAUSE")) {
				serviceStatus = false;
			} else if (status.contains("START")) {
				serviceStatus = true;
				Log.e("Raj", "serviceStatus in onReceive : " + serviceStatus);
			}

			TimerTask addStatusTask = new TimerTask() {

				@Override
				public void run() {
					Server.addCurrentStatus(Server.getDate(), status);
				}
			};
			addStatusTask.run();

		}
	};

	@Override
	public void onLocationChanged(Location location) {
		mLat = location.getLatitude();
		mLng = location.getLongitude();
		mSpeed = location.getSpeed();
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
	}

	@Override
	public void onProviderEnabled(String provider) {
	}

	@Override
	public void onProviderDisabled(String provider) {
	}

	public void initializeLocationParameters() {
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		boolean isGPSEnabled = locationManager
				.isProviderEnabled(LocationManager.GPS_PROVIDER);
		boolean isNetworkEnabled = locationManager
				.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
		if (!isGPSEnabled && !isNetworkEnabled) {

		} else {
			if (locationManager != null) {
				if (isGPSEnabled) {
					locationManager.requestLocationUpdates(
							LocationManager.GPS_PROVIDER, 0, 0, this);
					mLocation = locationManager
							.getLastKnownLocation(LocationManager.GPS_PROVIDER);
				} else if (isNetworkEnabled) {
					locationManager.requestLocationUpdates(
							LocationManager.NETWORK_PROVIDER, 0, 0, this);
					mLocation = locationManager
							.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
				}
			}
			if (mLocation == null) {
				if (NetworkConnectivity.isConnectedToInternet(mContext)) {
					Criteria c = new Criteria();
					String mBestProvider = locationManager.getBestProvider(c,
							true);
					locationManager.requestLocationUpdates(mBestProvider, 0, 0,
							this);
					mLocation = locationManager
							.getLastKnownLocation(mBestProvider);
				}
			}
			if (mLocation != null) {
				mLat = mLocation.getLatitude();
				mLng = mLocation.getLongitude();
			}
		}
	}

	public void addPosition() {
		BusPosition position = new BusPosition(Double.toString(mLat),
				Double.toString(mLng), Double.toString(mSpeed),
				Server.getDate());
		safeList.add(position);
		mFlag = true;
	}

	public void uploadData() {
		if (NetworkConnectivity.isConnectedToInternet(mContext))
			return;
		while (safeList.size() > 0) {
			BusPosition position = null;
			if (mFlag && NetworkConnectivity.isConnectedToInternet(mContext)) {
				position = safeList.get(0);
				safeList.remove(0);
			}
			if (position != null)
				Server.addPosition(position.getLat(), position.getLng(),
						position.getSpeed(), position.getTime());

		}
	}

	TimerTask uploadTask = new TimerTask() {
		@Override
		public void run() {
			if (serviceStatus)
				uploadData();
		}
	};

	TimerTask addTask = new TimerTask() {
		@Override
		public void run() {
			if (serviceStatus)
				addPosition();
		}
	};
}
